package org.aeon.gamechatnest.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.aeon.gamechatnest.common.Constant;
import org.aeon.gamechatnest.common.response.RespStatus;
import org.aeon.gamechatnest.common.response.Result;
import org.aeon.gamechatnest.common.response.ResultBuild;
import org.aeon.gamechatnest.dto.ChatMessageMatchDto;
import org.aeon.gamechatnest.pojo.ChatMessage;
import org.aeon.gamechatnest.pojo.PrivateLetter;
import org.aeon.gamechatnest.service.PrivateChatMessageService;
import org.aeon.gamechatnest.service.PrivateLetterService;
import org.aeon.gamechatnest.socket.ChatMessageClient;
import org.aeon.gamechatnest.util.ApplicationAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Deque;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author : Qik 2024/5/15 11:38
 */
@Slf4j
@Service
public class PrivateChatMessageServiceImpl implements PrivateChatMessageService {

    @Autowired
    @Lazy
    private PrivateLetterService privateLetterService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public Result syncMessage(Long userId) {
        List<Long> privateLetterIds = privateLetterService.findIdByUserId(userId);
        // 查询私信的同步消息库
        List<ChatMessage> chatMessages = mongoTemplate.findAllAndRemove(
                new Query(Criteria.where("targetId").in(privateLetterIds)),
                ChatMessage.class, Constant.PRIVATE_SYNCHRONIZE_MESSAGE
        );
        return ResultBuild.result().state(RespStatus.MESSAGE_SYNCHRONIZATION_SUCCESSFUL).data(chatMessages).build();
    }

    @Override
    public void handleMessage(ConcurrentHashMap<Long, ChatMessageClient> webSocketMap, ChatMessage chatMessage) {
        // 获取登录用户id
//        Long loginUserId = SecurityUtil.getUserId();

        // 消息发送用户id
        Long userId = chatMessage.getFromUser();

        // 当前用户的响应队列
        Deque<Object> responseQueue = webSocketMap.get(userId).getResponseQueue();

        // 获取私信
        PrivateLetter privateLetter = privateLetterService.findById(chatMessage.getTargetId());
        // 私信对话不存在
        if (Objects.isNull(privateLetter)) {
            responseQueue.addFirst(ResultBuild.result().state(RespStatus.TARGET_CONVERSATION_NOT_FOUND_ERROR).build());
            return;
        }
        // 私信对话不包含当前用户 TODO 修改
        if (!privateLetter.getFromUser().equals(userId) && !privateLetter.getToUser().equals(userId)) {
            responseQueue.addFirst(ResultBuild.result().state(RespStatus.NO_ACCESS_PERMISSION_TO_TARGET_CONVERSATION).build());
            return;
        }

        // 获取对方用户id
        Long toUserId = privateLetter.getToUser().equals(userId) ? privateLetter.getFromUser() : privateLetter.getToUser();

        // 获取对方在线会话
        ChatMessageClient chatMessageClient = webSocketMap.get(toUserId);

        if (chatMessageClient == null) {
            // 如果不在线，储存到同步消息库
            log.debug("用户id:{}不在线，储存到同步消息库，消息id:{}", toUserId, chatMessage.getId());
            mongoTemplate.save(chatMessage, Constant.PRIVATE_SYNCHRONIZE_MESSAGE);
        } else {
            // 在线，直接发送给对方
            chatMessageClient.getResponseQueue().addFirst(ResultBuild.result()
                    .state(RespStatus.MESSAGE_RECEIVED_SUCCESSFULLY)
                    .data(chatMessage)
                    .build());
        }
        // 同时存入历史消息库
        mongoTemplate.save(chatMessage, Constant.PRIVATE_HISTORICAL_MESSAGE);

        responseQueue.addFirst(ResultBuild.result()
                .state(RespStatus.MESSAGE_SENT_SUCCESSFULLY)
                .data(chatMessage)
                .build());
    }

    @Override
    public List<ChatMessage> historyMessage(ChatMessageMatchDto chatMessageOperation) {
        // 查询历史消息库，指定私信id
        Criteria criteria = Criteria.where("targetId").is(chatMessageOperation.getTargetId());

        // 指定开始时间
        if (Objects.nonNull(chatMessageOperation.getStartTime())) {
            criteria.and("createTime").gte(chatMessageOperation.getStartTime());
        }

        // 指定结束时间
        if (Objects.nonNull(chatMessageOperation.getEndTime())) {
            criteria.and("createTime").lte(chatMessageOperation.getEndTime());
        }

        // 指定开始消息
        if (Objects.nonNull(chatMessageOperation.getMessageId())) {
            ChatMessage byId = mongoTemplate.findById(chatMessageOperation.getMessageId(),
                    ChatMessage.class, Constant.PRIVATE_HISTORICAL_MESSAGE);
            ApplicationAssert.nonNull(byId, "非法消息id");
            assert byId != null;
            criteria.and("createTime").lt(byId.getCreateTime());
        }

        return mongoTemplate.find(
                // TODO 默认条数
                new Query(criteria).with(Sort.by(Sort.Direction.DESC, "createTime")).limit(Objects.requireNonNullElse(chatMessageOperation.getLimit(), 10)),
                ChatMessage.class, Constant.PRIVATE_HISTORICAL_MESSAGE
        );
    }

    @Override
    public List<ChatMessage> removeById(String messageId) {
        return null;
    }
}
